﻿namespace EAL.Database
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using EAL.Models;
    using System.Linq;

    public class OrderList : ObservableCollection<Order>
    {
        private readonly DbContext _context;


        /// <summary>
        /// ctor receiving a list of orders as data source and the data context the order list
        /// was retrieved from
        /// </summary>
        /// <param name="customers">list of orders used as data source</param>
        /// <param name="context">data context the order list was retrieved from</param>
        public OrderList(IEnumerable<Order> orders, DbContext context)
            : base(orders)
        {
            this._context = context;

            //register change notification handler to every orders positions list to react when a position
            //is added or removed
            //foreach (Order o in orders)
            //    o.Positions.AssociationChanged += Positions_AssociationChanged;

            //subscribe to property changed event of each order in the list
            //(
            //and in addition create for every order detail (position) a special
            //kind of list
            //)
            //and register to property changed event of the positions list of each order
            //to validate the amount of products per order
            foreach (Order item in orders)
            {
                item.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(item_PropertyChanged);

                //if (null == item.Positions)
                //    item.Positions = new PositionList(null, this._context);
                //else
                //    item.Positions = new PositionList(item.Positions, this._context);
            }
        }


        /// <summary>
        /// overridden insert method to add a new order to the list and the underlying data context
        /// </summary>
        /// <param name="index">index to insert the item into the list</param>
        /// <param name="item">item to insert</param>
        protected override void InsertItem(int index, Order item)
        {
            //item.Positions.AssociationChanged += Positions_AssociationChanged;

            //add item to data context, too
            this._context.Orders.Add(item);

            //add item to list itself
            base.InsertItem(index, item);
        }

        /// <summary>
        /// removes an item from the collection and the data context
        /// </summary>
        /// <param name="index">index of the item to remove</param>
        protected override void RemoveItem(int index)
        {
            //remove event handler from the positions list
            //this.Items[index].Positions.AssociationChanged -= Positions_AssociationChanged;

            ////delete all positions related to the order to remove
            //foreach (Position p in this.Items[index].Positions)
            //    this._context.Positions.Remove(p);

            //remove item from context ...
            this._context.Orders.Remove(this.Items[index]);

            //... unsubscribe from property changed event of that item ...
            this.Items[index].PropertyChanged -= item_PropertyChanged;

            //... and remove it from collection itself, too
            base.RemoveItem(index);
        }

        /// <summary>
        /// called when a property of a containing order was changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            //call simply base method
            //(the logic exists already, but have to be called manually)
            this.OnPropertyChanged(e);
        }

        /// <summary>
        /// event raised when a position (related to an order) is removed from the collection
        /// removes the position from the database context
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Positions_AssociationChanged(object sender, CollectionChangeEventArgs e)
        {
            if (e.Action == CollectionChangeAction.Remove)
                this._context.Positions.Remove((Position)e.Element);
        }
    }
}
